package com.lsh.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author ：LiuShihao
 * @date ：Created in 2021/3/18 9:59 上午
 * @desc ：RabbitMQ配置类
 *
 * 用来确认生产者 producer 将消息发送到 broker ，
 * broker 上的交换机 exchange 再投递给队列 queue的过程中，消息是否成功投递。
 *
 * 消息从 producer（生产者） 到 rabbitmq broker （消息队列服务器）有一个 confirmCallback 确认模式。
 * 消息从 exchange（交换机） 到 queue （队列）投递失败有一个 returnCallback 退回模式。
 * 我们可以利用这两个Callback来确保消的100%送达。
 *
 */
@Configuration
public class RabbitMQConfig {
    public RabbitMQConfig() {
        System.out.println("加载RabbitMQConfig...");
    }

    /**
     * 创建一个队列
     *
     * @durable 队列是否可持久化，默认为true。
     * @exclusive 队列是否具有排它性，默认为false。
     * @autoDelete 队列没有任何订阅的消费者时是否自动删除，默认为false。可以通过RabbitMQ Management，查看某个队列的消费者数量。如果为true，当consumers = 0时队列就会自动删除。
     * @return
     */
    @Bean("Queue")
    public Queue getQueue(){
        return new Queue("queue",true,false,false);
    }

    /**
     * 创建交换机
     *
     * RabbitMQ提供了四种Exchange：fanout,direct,topic,header
     * header模式在实际使用中较少，本文只对前三种模式进行比较。
     * 性能排序：fanout > direct >> topic。比例大约为11：10：6
     * @return
     */
    @Bean
    public FanoutExchange confirmTestExchange() {
        return new FanoutExchange("confirmTestExchange");
    }

    /**
     * 将队列绑定到交换机上
     * @param confirmTestExchange   上面创建交换机
     * @param confirmTestQueue      上面创建的队列
     * @return
     */
    @Bean
    public Binding confirmTestFanoutExchangeAndQueue(
            @Qualifier("confirmTestExchange") FanoutExchange confirmTestExchange,
            @Qualifier("Queue") Queue confirmTestQueue) {
        return BindingBuilder.bind(confirmTestQueue).to(confirmTestExchange);
    }
}
